package testmybatis;

import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import testmybatis.springmybatis.MyMybatisFactoryBean;
import testmybatis.mapper.CompanyMapper;
import testmybatis.mapper.MemberMapper;
import testmybatis.service.CompanyService;
import testmybatis.service.MemberService;

/**
 * @Description TODO
 * @Author dangxianyue
 * @Date 2024/3/27 15:43
 */
public class TestMybatis {
    public static void main(String[] args) {
        // test1();
        // test2();
        test3();
    }

    /**
     * 测试一个Mapper对应着一个FactoryBean类
     * 要开启配置扫描@ComponentScan("testmybatis.springmybatis")
     * 同时FactoryBean上也要有@Component注解，让FactoryBean给Spring创建
     */
    public static void test1() {
        final AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(TestMybatisAppConfig.class);
        System.out.println("sqlSessionFactory: " + applicationContext.getBean("sqlSessionFactory"));

        // 这样实际上获取的是Mapper接口的代理对象
        System.out.println("memberMapperProxy: " + applicationContext.getBean("myMybatisFactoryBean"));
        // 这样才是获取到真正的FactoryBean
        System.out.println("memberFactoryBean: " + applicationContext.getBean("&myMybatisFactoryBean"));
        // 获取MemberService，测试成功注入了MemberMapper
        MemberService memberService = (MemberService) applicationContext.getBean("memberService");
        System.out.println("memberService: " + memberService);
        memberService.test();// member
    }

    /**
     * 测试多个Mapper可以共用一个FactoryBean的情况
     * 需要取消两个地方的注解：
     * 1. MyMybatisFactoryBean类上的@Component
     * 2. TestMybatisAppConfig类上的@ComponentScan("testmybatis.springmybatis")
     */
    public static void test2() {
        final AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
        applicationContext.register(TestMybatisAppConfig.class);

        final AbstractBeanDefinition beanDefinition1 = BeanDefinitionBuilder.genericBeanDefinition().getBeanDefinition();
        beanDefinition1.setBeanClass(MyMybatisFactoryBean.class);
        beanDefinition1.getConstructorArgumentValues().addGenericArgumentValue(MemberMapper.class);
        applicationContext.registerBeanDefinition("memberMapper", beanDefinition1);

        final AbstractBeanDefinition beanDefinition2 = BeanDefinitionBuilder.genericBeanDefinition().getBeanDefinition();
        beanDefinition2.setBeanClass(MyMybatisFactoryBean.class);
        beanDefinition2.getConstructorArgumentValues().addGenericArgumentValue(CompanyMapper.class);
        applicationContext.registerBeanDefinition("companyMapper", beanDefinition2);

        applicationContext.refresh();

        MemberService memberService = (MemberService) applicationContext.getBean("memberService");
        memberService.test();// member

        CompanyService companyService = (CompanyService) applicationContext.getBean("companyService");
        companyService.test();// company
    }

    /**
     * 测试通过ImportBeanDefinitionRegistrar注册
     */
    public static void test3() {
        final AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(TestMybatisAppConfig.class);

        MemberService memberService = (MemberService) applicationContext.getBean("memberService");
        memberService.test();// member

        CompanyService companyService = (CompanyService) applicationContext.getBean("companyService");
        companyService.test();// company
    }
}
